package com.ltmonitor.web.controller.command;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ltmonitor.service.*;
import com.ltmonitor.video.entity.VideoServerConfig;

import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ltmonitor.entity.Alarm;
import com.ltmonitor.entity.BasicData;
import com.ltmonitor.entity.JT809Command;
import com.ltmonitor.entity.TerminalCommand;
import com.ltmonitor.entity.VehicleData;
import com.ltmonitor.util.Constants;
import com.ltmonitor.util.DateUtil;
import com.ltmonitor.vo.PaginateResult;
import com.ltmonitor.web.controller.GenericAction;
import com.ltmonitor.web.controller.PaginateAction;
import com.ltmonitor.web.util.JsonMessage;
import com.ltmonitor.web.util.OnlineUser;

@Controller
@RequestMapping("/command")
public class TerminalCommandAction extends PaginateAction {

	/**
	 * 终端命令服务
	 */
	@Autowired
	protected ITerminalCommandService terminalCommandService;

	@Autowired
	protected IJT809CommandService jt809CommandService;


	/**
	 * 获取终端命令的执行结果
	 * @param commandId
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/getCommandResult.action")
	public JsonMessage getCommandResult(long commandId) {
		TerminalCommand tc = getTerminalCommand(commandId);
		BasicData bd = getBasicDataService().getBasicDataByCode(tc.getStatus(),
				"TCommandStatus");
		String status = bd != null ? bd.getName() : "";
		if (TerminalCommand.STATUS_NEW.equals(tc.getStatus()) == false
				&& TerminalCommand.STATUS_PROCESSING.equals(tc.getStatus()) == false) {
			return json(true, status);
		}

		return json(false, status);
	}


	protected void SendCommand(TerminalCommand tc) {
		SendCommand(tc, tc.getVehicleId());
	}

	protected void SendCommand(TerminalCommand tc,long vId) {
		VehicleData vd = vehicleDataService.load(vId);
		tc.setPlateNo(vd.getPlateNo());
		tc.setSimNo(vd.getSimNo());
		tc.setVehicleId(vd.getEntityId());
		OnlineUser onlineUser = getOnlineUser();
		if (onlineUser != null) {
			tc.setUserId(onlineUser.getEntityId());
			tc.setOwner(onlineUser.getName());

			Integer cmdType = tc.getCmdType();
			String strCmd = Integer.toHexString(cmdType);
			while (strCmd.length() < 4)
				strCmd = "0" + strCmd;
			strCmd = "0x" + strCmd;
			String descr = JT808Constants.GetDescr(strCmd);

			this.LogOperation(vd.getPlateNo() + "下发" + descr + "[" + strCmd
					+ "]命令");

		}
		this.terminalCommandService.save(tc);
	}

	protected TerminalCommand getTerminalCommand(long commandId) {
		return (TerminalCommand) this.terminalCommandService.load(commandId);
	}

	/**
	 * 分页查询终端命令列表
	 * 
	 * @return
	 */
	@RequestMapping("/commandList.action")
	@ResponseBody
	public PaginateResult query(@RequestParam(value="page", defaultValue="1") int  page,
			@RequestParam(value="rows", defaultValue="10") int rows)
	{
		Map params = new HashMap();
		params.put("userId", this.getOnlineUser().getEntityId());// 根据用户权限查询自己的终端命令
		params.put("startDate", DateUtil.dateToString(new Date()));
		// params.put("depIdList", super.getAuthorizedDepIdList());//
		// 只查询本部门的车辆的终端上报消息
		String queryId = "terminalCommand.selectTerminalCommand";
		if (getOnlineUser() != null) {
			// 只查询用户自己下发的命令
			// params.put("userId", getOnlineUser().getEntityId());
		}
		try {
			PaginateResult result = queryService.queryByPagination(queryId,
					params, page, rows);
			for (Object obj : result.getRows()) {
				Map rowData = (Map) obj;

				Date createDate = (Date) rowData.get("createDate");
				rowData.put("createDate",
						DateUtil.toStringByFormat(createDate, "MM-dd HH:mm:ss"));

				Date updateDate = (Date) rowData.get("updateDate");
				rowData.put("updateDate",
						DateUtil.toStringByFormat(updateDate, "MM-dd HH:mm:ss"));

				Integer cmdType = (Integer) rowData.get("cmdType");
				String strCmd = Integer.toHexString(cmdType);
				while (strCmd.length() < 4)
					strCmd = "0" + strCmd;
				strCmd = "0x" + strCmd;
				String descr = JT808Constants.GetDescr(strCmd);
				rowData.put("cmdType", descr);

				String commandStatus = "" + rowData.get("status");
				BasicData bd = getBasicDataService().getBasicDataByCode(
						commandStatus, "TCommandStatus");
				if (bd != null) {
					rowData.put("status", bd.getName());
				}
			}
			return result;

		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
		return new PaginateResult();
	}

	/**
	 * 当发生报警时，需要进行拍照，监听，文本下发等命令下发时，同时更新处理报警信息
	 * 
	 * @param alarmId
	 */
	protected void processAlarm(long alarmId, int processType,String processedRemark) {
		if (alarmId == 0)
			return;
		Alarm alarm = this.getAlarm(alarmId);
		alarm.setRemark(processedRemark);
		alarm.setProcessed(processType);
		alarm.setProcessedTime(new Date());
		OnlineUser onlineUser = this.getOnlineUser();
		if (onlineUser != null) {
			alarm.setProcessedUserId(onlineUser.getEntityId());
			alarm.setProcessedUserName(onlineUser.getName());
		}
		// this.getBaseService().saveOrUpdate(alarm);
		String tableName = Constants.getAlarmTableName();
		alarm.setTableName(tableName);
		String statementName = "updateAlarmProcessedState";
		this.queryService.update(statementName, alarm);

		this.LogOperation(alarm.getPlateNo() + "报警处理");

		/**
		 * 809命令，主动上报转发给上级平台的报警处理结果
		 */
		JT809Command jc = new JT809Command();
		try {
			int subCmd = 0x1403;
			jc.setCmd(0x1400);
			jc.setSubCmd(subCmd);
			int result = 1;
			jc.setCmdData(alarm.getEntityId() + ";" + result);
			String hql = "from VehicleData where plateNo = ?";
			VehicleData vd = (VehicleData) this.vehicleDataService.getVehicleByPlateNo(alarm.getPlateNo());
			jc.setPlateNo(vd.getPlateNo());
			jc.setPlateColor((byte) vd.getPlateColor());

			// OnlineUser onlineUser = getOnlineUser();
			if (onlineUser != null) {
				jc.setOwner(onlineUser.getName());
				jc.setUserId(onlineUser.getEntityId());
			}
			this.jt809CommandService.save(jc);
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	/**
	 * 通过alarm表格中的id索引获取到alarm的值
	 * 备注：返回值中的alarmNo变量保存的是alarmIndex的值，
	 * 目的是让processAdasAlarmByAlarmIds方法可以使用本方法，提高代码效率
	 * @param alarmId
	 * @return
	 */
	protected  Alarm getAlarm(long alarmId) {
		Map params = new HashMap();
		String tableName = Constants.getAlarmTableName();
		params.put("tableName", tableName);// 报警数据是一个月一张表
		params.put("alarmId", alarmId);
		// Date date = DateUtil.getDate(new Date(), Calendar.MINUTE, -2); //
		// 当前一分钟内产生的报警
		// params.put("startTime", date);
		String queryId = "selectNewAlarms";
		List<Map<String,Object>> result = this.queryService.query(queryId, params);
		// result = filterAlarmResult(result);
		Alarm alarm = new Alarm();
		// alarmData.put("alarm", result);
		if (result.size() > 0) {
			Map a = (Map) result.get(0);
			// this.convert(a);
			alarm.setEntityId((Integer) a.get("id"));
			alarm.setVehicleId((Integer) a.get("vehicleId"));
			if (a.containsKey("ackSn"))
				alarm.setAckSn((Integer) a.get("ackSn"));
			alarm.setPlateNo("" + a.get("plateNo"));
			alarm.setAlarmType("" + a.get("alarmTypeDescr"));
			alarm.setLocation("" + a.get("location"));
			if (a.get("remark") != null)
				alarm.setRemark("" + a.get("remark"));
			else
				alarm.setRemark("已处理");
			alarm.setAlarmTime((Date) a.get("alarmTime"));
			
			//添加alarmNo数据信息，author：shinion，date：2018-12-28
			if(a.get("alarmIndex") != null) {
				alarm.setAdasAlarmNo(""+a.get("alarmIndex"));
			}else {
				alarm.setAdasAlarmNo("");
			}
			
		}

		return alarm;
	}

	protected static boolean isNumeric(String str) {
		if (str.matches("\\d*")) {
			return true;
		}
		return false;
	}

	/**
	 * author：shinion
	 * date：2018-12-26
	 * 当发生警报，需要进行拍照，监听，文本下发等命令时，同时更新处理报警信息
	 * 发送809平台的报警alarmId为gps_hisdata.alarm表格中的id信息，目的为统一目前的通讯协议，如果查找报警信息，可以找到。
	 * 更新数据表格为：subiaodb.adasAlarm，
	 * 
	 * @param alarmIds 报警信息在alarm表中的id
	 * @param adasAlarmIds Adas报警信息在adas表中的id
	 * @param processType 处理方式
	 */
	protected void processAdasAlarms(List list,long[] alarmIds,long[] adasAlarmIds,int processType,String processedRemark) {
		try {
			//判别数据存在，如果不存在则不处理
			if(alarmIds.length > 0 && adasAlarmIds.length > 0) {
				OnlineUser onlineUser = this.getOnlineUser();//获取在线用户
				if (onlineUser != null) {
					//定义更新语句
					String statementName = "adasAlarm.updateAdasAlarmProcessedState";//更新处理状态
					String statementName2 = "alarm.updateAdasAlarmProcessedNum";//更新数量
					Map params = new HashMap();
					// 遍历，获取adasAlarm信息，更新数据
					for (int i = 0; i < adasAlarmIds.length; i++) {
						Alarm alarm = this.getAdasAlarm(list,adasAlarmIds[i]);
//						list.add("getSlarmValue->"+alarm.toString());
						if(alarm != null) {
							list.add(alarm.getAdasAlarmNo());//链表中添加数据
							alarm.setRemark(processedRemark);
							alarm.setProcessed(processType);
							alarm.setProcessedTime(new Date());
							alarm.setProcessedUserId(onlineUser.getEntityId());
							alarm.setProcessedUserName(onlineUser.getName());
							//更新记录
							this.queryService.update(statementName, alarm);
							//更新处理数量
							params.clear();
							params.put("adasAlarmIndex", alarm.getAdasAlarmNo());
							params.put("processed", processType);
							params.put("processedTime", new Date());
							params.put("processedUserId", onlineUser.getEntityId());
							params.put("processedUserName", onlineUser.getName());
							params.put("remark", processedRemark);
							System.out.println("++++++++++++++++++++++");
							System.out.println("++++++++++++++++++++++");
							System.out.println("更新数量");
							System.out.println(params);
							this.queryService.update(statementName2, params);
							System.out.println("更新数量完成");
							//日志记录
							this.LogOperation(alarm.getPlateNo() + "报警处理");
							
						}
					}//end adasAlarms
					
					
					//发送809指令
					send809Command(alarmIds);
					
					
				}//end onlineUser
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			log.error(e.getMessage(),e);
		}
		
	}

	
	/**
	 * author:shinion
	 * date:2018-12-27
	 * 处理单条主动安全报警信息，会更新adasAlarm表下该alarmIndex所有相关报警记录
	 * @param adasAlarmIndexs Adas报警信息在alarm表中的id字段
	 * @param processType 处理方式
	 */
	protected void processAdasAlarmByAlarmIds(List list,long[] alarmIdsForAdas,int processType,String processedRemark) {
		/*
		 * 1.通过alarm表中的id获取index，
		 *	2更新所有没有处理过的记录的处理状态信息
		 *	3.更新alarm表中的处理数量等于报警总数
		 *	4发送809指令
		 * 
		 * */
		try {
			//获取alarm
			if(alarmIdsForAdas.length > 0) {
				
				OnlineUser onlineUser = this.getOnlineUser();//获取在线用户
				if(onlineUser != null) {
					//定义更新sql
					String statementName = "adasAlarm.updateOneAdasAllUnProcessedState";//更新adasAlarm表中该报警所有未处理记录的状态
					String statementName2 = "alarm.updateAdasAlarmAllProcessed";//更新alarm表中的数量,为全部处理完成
					//遍历开始处理
					 int num = 1;
					for (long alarmId : alarmIdsForAdas) {
						Alarm alarm = getAlarm(alarmId);
						//判断如果index为空，则不处理
						if (alarm != null && (!alarm.getAdasAlarmNo().equals(""))) {
							// 更新adasAlarm表中单个alarmIndex 所有没有处理过的记录
							alarm.setRemark(processedRemark);
							alarm.setProcessed(processType);
							alarm.setProcessedTime(new Date());
							alarm.setProcessedUserId(onlineUser.getEntityId());
							alarm.setProcessedUserName(onlineUser.getName());
							list.add(num+"->"+alarm.getAdasAlarmNo());
							num++;
							if(!alarm.getAdasAlarmNo().equals("")) {
								//index 不为空，则更新
								//更新记录
								this.queryService.update(statementName, alarm);
								
								
								//更新处理数量
								this.queryService.update(statementName2, alarm);
								
							}
							
							
						} // end alarm
					}
					
					
					//发送809 信息
					send809Command(alarmIdsForAdas);

				}
				
				
				
				
				
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			log.error(e.getMessage(),e);
		}
		
	}
	
	
	
	/**
	 * 发送809消息
	 * @param alarmIds
	 */
	private void send809Command(long[] alarmIds) {
		try {
			if(alarmIds.length > 0) {
				/**
				 * 809命令，主动上报转发给上级平台的报警处理结果
				 */
				System.out.println("++++++++++++++++++++++");
				System.out.println("++++++++++++++++++++++");
				System.out.println("总共需要转发809"+alarmIds.length+"条信息");
				OnlineUser onlineUser = this.getOnlineUser();//获取在线用户
				for (int j=0 ; j<alarmIds.length ; j++) {
					Alarm alarm2 = this.getAlarm(alarmIds[j]);
					if(alarm2 != null) {
						JT809Command jc = new JT809Command();
						int subCmd = 0x1403;
						jc.setCmd(0x1400);
						jc.setSubCmd(subCmd);
						int result = 1;
						jc.setCmdData(alarm2.getEntityId() + ";" + result);
						String hql = "from VehicleData where plateNo = ?";
						VehicleData vd = (VehicleData) this.vehicleDataService.getVehicleByPlateNo(alarm2.getPlateNo());
						jc.setPlateNo(vd.getPlateNo());
						jc.setPlateColor((byte) vd.getPlateColor());

						// OnlineUser onlineUser = getOnlineUser();
						if (onlineUser != null) {
							jc.setOwner(onlineUser.getName());
							jc.setUserId(onlineUser.getEntityId());
						}
						this.jt809CommandService.save(jc);
						System.out.println("++++++++++++++++++++++");
						System.out.println("转发809成功一条");
					}
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			log.error(e.getMessage(),e);
		}
	}
	
	
	/**
	 * author:shinion
	 * date:2018-12-26
	 * 根据adasAlarmId索引获取报警信息
	 *借用alarm的类对象保存数据，实际对象里面保存的是adasAlarm里面的内容
	 * @param adasAlarmId adasAlarm 表格中的id字段
	 * @return
	 */
	private Alarm getAdasAlarm(List list,long adasAlarmId) {
		Alarm alarm = new Alarm();
		
		try {
			String queryId = "adasAlarm.selectOneAdasAlarm";
			Map params = new HashMap();
			params.put("adasAlarmId", adasAlarmId);
			List<Map<String, Object>> result = this.queryService.query(queryId, params);
			if (result.size() > 0) {
//				list.add("getAdasAlarm->Num" + result.toString());
				Map<String, Object> a = (Map) result.get(0);
				Long id = (Long) a.get("id");
//				alarm.setEntityId(id.longValue());
				alarm.setEntityId((Long)a.get("id"));
				alarm.setPlateNo("" + a.get("plateNo"));
				if (a.get("alarmIndex") != null) {
					alarm.setAdasAlarmNo("" + a.get("alarmIndex"));
				} else {
					alarm.setAdasAlarmNo("");
				}
//				list.add("getAlarmNo->" + alarm.getAdasAlarmNo());
//				list.add("alarmValue->" + alarm.toString());
			}
		} catch (Exception e) {
			// TODO: handle exception
//			list.add("error"+e.toString());
			e.printStackTrace();
		}
		
		
		return alarm;
	}

}
